package com.hsy.swu.home.course

import android.content.Context
import android.content.res.ColorStateList
import android.text.Html
import android.util.AttributeSet
import android.view.MotionEvent
import android.view.View
import android.view.ViewGroup
import android.view.animation.BounceInterpolator
import android.view.animation.DecelerateInterpolator
import android.widget.TextView
import androidx.core.view.children
import androidx.core.view.contains
import androidx.lifecycle.MutableLiveData
import com.hsy.swu.MyConfig
import com.hsy.swu.R
import com.hsy.swu.databinding.DialogCourseBinding
import com.hsy.swu.hsyutils.HsyDialog
import com.hsy.swu.hsyutils.MActivityUtil
import com.hsy.swu.hsyutils.setFont
import java.util.Stack

class CourseTableViewGroup(context: Context, attrs: AttributeSet?) : ViewGroup(context, attrs) {
    private var aWidth = 0
    private var aHeight = 0

    var courseList: List<CourseModel>? = null

    val dateList = CourseUtils.generateWeeksList(MyConfig.semesterStartDate)
    val currentWeek = MutableLiveData(MyConfig.currentWeek) // 初始值为当前周

    private var isFirstTimeShow = true

    override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec)
        if (aWidth == 0 && aHeight == 0) {
            aWidth = width / 7
            aHeight = height / 14
        }
    }

    override fun onLayout(changed: Boolean, left: Int, top: Int, right: Int, bottom: Int) {
        courseList ?: return
        val gap = 3
        repeat(courseList!!.size) { position ->
            val course = courseList!![position]
            course.apply {
                recycleCourseTv()
                obtainCourseTv()
                tv?.let { tv ->
                    if (!contains(tv)) { // 不在才加
                        addView(tv)
                        tv.animate().scaleX(0.8f).scaleY(0.8f).alpha(0f).setDuration(0).start()
                        MActivityUtil.scaleAnimOnShow(tv, 0.8f)
                        if (!course.isInWeek(currentWeek.value!!)) {
                            tv.visibility = View.INVISIBLE
                        }
                        tv.layout(
                            (dayOfWeek - 1) * aWidth + gap,
                            (startSection - 1) * aHeight + gap,
                            dayOfWeek * aWidth - gap,
                            (startSection - 1 + totalSection) * aHeight - gap
                        )
                    }
                }
            }
        }

        // 添加完所有子 View，则 setFont
        setFont()

        if (isFirstTimeShow && childCount != 0) {
            isFirstTimeShow = false
            firstTimeShow()
        }
    }

    private var isOnInterceptTouch = true // OnInterceptTouchEvent实在进入不到 ACTION_MOVE才自己写了一个标志位
    private var startX = 0f

    override fun dispatchTouchEvent(ev: MotionEvent?): Boolean {
        requestDisallowInterceptTouchEvent(true)
//        MLog.attention("dispatchTouchEvent")
        when (ev?.action) {
            MotionEvent.ACTION_DOWN -> {
//                MLog.attention("dispatchTouchEvent: ACTION_DOWN")
                startX = ev.x
            }

            MotionEvent.ACTION_UP -> {
//                MLog.attention("dispatchTouchEvent: ACTION_UP")
                if (isOnInterceptTouch) {
                    if (ev.x - startX > 150f) pageLeft()
                    if (ev.x - startX < -150f) pageRight()
                    startX = 0f
                }
            }
        }
        return super.dispatchTouchEvent(ev)
    }

    override fun onInterceptTouchEvent(ev: MotionEvent?): Boolean {
//        MLog.attention("onInterceptTouchEvent")
        when (ev?.action) {
            MotionEvent.ACTION_DOWN -> {
//                MLog.attention("onInterceptTouchEvent: ACTION_DOWN")
            }

            MotionEvent.ACTION_MOVE -> {
//                MLog.attention("onInterceptTouchEvent: ACTION_MOVE")
            }

            MotionEvent.ACTION_UP -> {
//                MLog.attention("onInterceptTouchEvent: ACTION_UP")
            }
        }
        return super.onInterceptTouchEvent(ev)
    }

    override fun onTouchEvent(event: MotionEvent?): Boolean {
//        MLog.attention("onTouchEvent")
        when (event?.action) {
            MotionEvent.ACTION_MOVE -> {
//                MLog.attention("onTouchEvent: ACTION_MOVE")
                isOnInterceptTouch = false // 只要进到这里就不是 OnInterceptTouch
            }

            MotionEvent.ACTION_UP -> {
//                MLog.attention("onTouchEvent: ACTION_UP")
                if (event.x - startX > 150f) pageLeft()
                if (event.x - startX < -150f) pageRight()
                startX = 0f
                isOnInterceptTouch = true
            }
        }
        return true
    }

    private fun pageLeft() { // 向左翻页
        if (currentWeek.value == 1) {
            MActivityUtil.showToast("已是第一周")
        } else {
            currentWeek.postValue(currentWeek.value!! - 1)
        }
    }

    private fun pageRight() { // 向右翻页
        if (currentWeek.value == dateList.size / 7) {
            MActivityUtil.showToast("已是最后一周")
        } else {
            currentWeek.postValue(currentWeek.value!! + 1)
        }
    }

    fun checkCourseIsInWeek(currentWeek: Int) {
        courseList ?: return
        children.forEachIndexed { index, tv ->
            if (!courseList!![index].isInWeek(currentWeek)) {
                if (tv.visibility == View.VISIBLE) {
                    MActivityUtil.scaleAnimOnDismiss(tv) {
                        tv.visibility = View.INVISIBLE
                    }
                }
            } else {
                if (tv.visibility == View.INVISIBLE) {
                    tv.animate().scaleX(0.8f).scaleY(0.8f).alpha(0f).setDuration(0).start()
                    tv.visibility = View.VISIBLE
                    MActivityUtil.scaleAnimOnShow(tv, 0.8f)
                }
            }
        }
    }

    // courseTv 复用
    private val courseTvStack by lazy {
        Stack<TextView>().apply {
            repeat(20) {
                push(initCourseTv())
            }
        }
    }

    private fun initCourseTv(): TextView {
        return TextView(context).apply {
            setBackgroundResource(R.drawable.bg_course)
            elevation = 50f
            setTextColor(resources.getColor(R.color.white))
            textSize = 9f
        }
    }

    private fun CourseModel.obtainCourseTv() {
        tv = if (courseTvStack.isEmpty()) {
            initCourseTv()
        } else {
            courseTvStack.pop()
        }.apply {
            if (classification == "custom") {
                backgroundTintList = ColorStateList.valueOf(resources.getColor(R.color.red))
            }
            text = Html.fromHtml(
                if (classification.contains("必")) {
                    "$courseName<br><br>" +
                            "->$classRoom<br>" +
                            "$teacher<br><br>" +
                            "<font color=\"#FF6060\">$classification</font>"
                } else {
                    "$courseName<br><br>" +
                            "->$classRoom<br>" +
                            "$teacher"
                },
                Html.FROM_HTML_MODE_COMPACT
            )

            setOnClickListener {
                object : HsyDialog<DialogCourseBinding>(context, { mBinding, _ ->
                    var mTogetherClass = ""
                    togetherClass.forEachIndexed { index, char ->
                        mTogetherClass += char
                        if (index != 0 && index % 16 == 0) {
                            mTogetherClass += "\n"
                        }
                    }

                    mBinding.apply {
                        tvTopCourseName.text = courseName
                        tvClassRoom.text = classRoom
                        tvTeacher.text = teacher
                        tvStudyWeek.text = studyWeek
                        tvCredit.text = credit.toString()
                        tvClassification.text = classification
                        tvTogetherClass.text = mTogetherClass
                    }
                }) {}.show()
            }
        }
    }

    private fun CourseModel.recycleCourseTv() {
        if (tv == null) return
        courseTvStack.push(
            tv?.apply {
                backgroundTintList = null
                text = ""
                setOnClickListener(null)
            }
        )
    }

    private fun courseViewMove() {
        children.forEach { v ->
            val mTranslationY = (measuredHeight - v.bottom).toFloat()
            val mDuration = ((mTranslationY / measuredHeight) * 3000).toLong()
            v.animate()
                .translationY(mTranslationY)
                .setDuration(mDuration)
                .setInterpolator(BounceInterpolator())
                .withEndAction {
                    v.animate()
                        .translationY(0f)
                        .setDuration(mDuration)
                        .setInterpolator(BounceInterpolator())
                        .start()
                }
                .start()
        }
    }

    private fun firstTimeShow() {
        children.forEach { v ->
            v.animate()
                .translationY(-1f * v.bottom)
                .setDuration(0)
                .start()
        }

        children.forEach { v ->
            v.animate()
                .translationY(0f)
                .setDuration(500)
                .setInterpolator(DecelerateInterpolator())
                .start()
        }
    }
}